package org.br.plotter.functions;

import java.util.*;
import java.lang.reflect.*;

import org.br.plotter.functions.math.*;

public class FunctionLocator {
	private static ExceptionHandler handler;
	final public static Map<String, EmbededFunctionExecuter> executer = new HashMap<String, EmbededFunctionExecuter>();
	static {	
		registerFunctions();
		loadRegisteredEmbededFunctions();
	}

	public static EmbededFunctionExecuter getFunction(String funct) {
		return executer.get(funct);
	}

	public static ExceptionHandler getExceptionHandler() {
		return handler;
	}

	public static void registerHandler(ExceptionHandler handlerEx) {
		handler = handlerEx;
	}

	public static void registerFunction(String functioName,
			EmbededFunctionExecuter execution) {
		executer.put(functioName, execution);
	}

	
	
   public static Set<String> getFunctions() {
	   return executer.keySet();
   
   }
   
   private static void registerFunctions(){
	   executer.put("abs",new Math_abs());
	   executer.put("acos",new Math_acos());
	   executer.put("asin",new Math_asin());
	   executer.put("atan",new Math_atan());
	   executer.put("atan2",new Math_atan2());
	   executer.put("cbrt",new Math_cbrt());
	   executer.put("ceil",new Math_ceil());
	   executer.put("copySign",new Math_copySign());
	   executer.put("cos",new Math_cos());
	   executer.put("cosh",new Math_cosh());
	   executer.put("exp",new Math_exp());
	   executer.put("expm1",new Math_expm1());
	   executer.put("floor",new Math_floor());
	   executer.put("getExponent",new Math_getExponent());
	   executer.put("hypot",new Math_hypot());
	   executer.put("IEEEremainder",new Math_IEEEremainder());
	   executer.put("log",new Math_log());
	   executer.put("log10",new Math_log10());
	   executer.put("log1p",new Math_log1p());
	   executer.put("max",new Math_max());
	   executer.put("min",new Math_min());
	   executer.put("nextAfter",new Math_nextAfter());
	   executer.put("nextUp",new Math_nextUp());
	   executer.put("pow",new Math_pow());
	   executer.put("random",new Math_random());
	   executer.put("rint",new Math_rint());
	   executer.put("round",new Math_round());
	   executer.put("scalb",new Math_scalb());
	   executer.put("signum",new Math_signum());
	   executer.put("sin",new Math_sin());
	   executer.put("sinh",new Math_sinh());
	   executer.put("sqrt",new Math_sqrt());
	   executer.put("tan",new Math_tan());
	   executer.put("tanh",new Math_tanh());
	   executer.put("toDegrees",new Math_toDegrees());
	   executer.put("toRadians",new Math_toRadians());
	   executer.put("ulp",new Math_ulp());

   }
	private static void loadRegisteredEmbededFunctions() {
		try {
			java.io.InputStream is = FunctionLocator.class
					.getResourceAsStream("/functions.properties");
			Properties props = new Properties();
			props.load(is);
			Set keys = props.keySet();
			for (Object obj : keys) {
				try {
					String key = obj.toString();
					String className = props.getProperty(key);
					Class cls = Class.forName(className);
					EmbededFunctionExecuter execution = (EmbededFunctionExecuter) cls
							.newInstance();
					executer.put(key, execution);
				} catch (Exception ex) {
				}
			}
		} catch (Exception ex) {
		}
	}

}
